package maze;

import java.util.Random;

/**
 * Created by Роман on 01.05.14.
 */
public class mazeMap
{
    int size;
    Cell[][] board;

    public mazeMap(int val)
    {
        size = val;
        board = new Cell[size][size];
        for(int i = 0; i < size; i++)
        {
            for(int j = 0; j < size; j++)
            {
                board[i][j] = new Cell();
            }
        }
    }

    public Cell[][] create()
    {
        Random rand = new Random();

        for(int i = 0; i < size; i++)
        {
            board[0][i].setMazeSet(i+1);
            board[0][i].setWall(3, true);
        }

        for(int i = 0; i < size; i++)
        {
            board[i][0].setWall(1, true);
            board[i][size-1].setWall(2, true);
            for(int j = 0; j < size; j++)
            {
                if(rand.nextBoolean())
                {
                    if(j != size-1)
                    {
//                        if((i == size-1)&&(board[i-1][j].getWall(4)))
//                            break;
//                        else
//                        {
                        if(board[i][j].getMazeSet() == board[i][j+1].getMazeSet())
                        {
                            board[i][j].setWall(2, true);
                            board[i][j+1].setWall(1, true);
                        }
                        else
                        {
                            board[i][j].setWall(2, true);
                            board[i][j+1].setWall(1, true);
                        }
//                        }
                    }
                }
                else
                {
                    if(j != size-1)
                    {
                        board[i][j+1].setMazeSet(board[i][j].getMazeSet());
                    }
                }
            }
            boolean flag = false;//there is no escape
            for(int j = 0; j < size && i != size-1; j++)
            {
                if(flag)//time to find exit
                {
                    if(rand.nextBoolean())
                    {
                        board[i][j].setWall(4, true);
                        board[i+1][j].setWall(3, true);
                        if(j!=0)
                        {
                            board[i+1][j].setMazeSet(board[i+1][j-1].getMazeSet() + 1);
                        }
                        else
                        {
                            board[i+1][j].setMazeSet(1);
                        }
                    }
                    else
                    {
                        board[i+1][j].setMazeSet(board[i][j].getMazeSet());
                    }
                    if(j != size-1)
                        if(board[i][j].getMazeSet() != board[i][j+1].getMazeSet())
                        {
                            flag = false;
                        }
//                    else
//                        {
//                            flag = false;
//                        }
                }
                else
                {
                    if(j != size-1)
                    {
                        if(board[i][j].getMazeSet() == board[i][j+1].getMazeSet())
                        {
                            if(rand.nextBoolean())
                            {
                                board[i][j].setWall(4, true);
                                board[i+1][j].setWall(3, true);
                                if(j!=0)
                                {
                                    board[i+1][j].setMazeSet(board[i+1][j-1].getMazeSet() + 1);
                                }
                                else
                                {
                                    board[i+1][j].setMazeSet(1);
                                }
                            }
                            else
                            {
                                flag = true;
                                board[i+1][j].setMazeSet(board[i][j].getMazeSet());
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                        if(j!=0)
                        {
                            board[i+1][j].setMazeSet(board[i+1][j-1].getMazeSet() + 1);
                        }
                        else
                        {
                            board[i+1][j].setMazeSet(1);
                        }
                    }
                }
            }
        }
        for(int j = 0; j < size; j++)
        {
            board[size-1][j].setWall(4, true);
            if(j != size-1)
                if(board[size-1][j].getMazeSet() != board[size-1][j+1].getMazeSet())
                {
                    board[size-1][j].setWall(2, false);
                    board[size-1][j+1].setWall(1, false);
                    board[size-1][j+1].setMazeSet(board[size-1][j].getMazeSet());
                }
        }

        for(int i = 0; i < size; i++)
            for(int j = 0; j < size; j++)
            {
                if(board[i][j].getWall(1) && board[i][j].getWall(2) && board[i][j].getWall(3) && board[i][j].getWall(4))
                {
                    if(j != size-1)
                    {
                        board[i][j].setWall(2, false);
                        board[i][j+1].setWall(1, false);
                    }
                    else
                    {
                        board[i][j].setWall(1, false);
                        board[i][j-1].setWall(2, false);
                    }
                }
            }
        return board;
    }

    public Cell[][] checkSpaces(Cell[][] maze)
    {
        for (int i = 0; i < size-1; i++)
        {
            for (int j = 0; j < size; j++)
            {
                int floor = 0;
                for (int z = 0; z < size && floor == 0; z++)
                {
                    if ((maze[i][j].getMazeSet() == maze[i][z].getMazeSet()) && (maze[i][z].getWall(4) == false))
                    {
                        floor++;
                    }
                }
                if (floor == 0)
                {
                    maze[j][i].setWall (2, false);
                    maze[j][i+1].setWall (1, false);
                }
            }
        }
        return maze;
    }

    public Cell[][] doorBuilder(Cell[][] maze)
    {
        boolean[] flag = {false, false, false, false};
        int rnd = 2 + (int)(Math.random() * (size-3));
        int tmp;
        do
        {
            tmp = (int)(Math.random() * 4);
            if (!flag[tmp]) // эта дверь ранее не устаналивалась
            {
                maze[0][rnd].setDoorType(tmp);
                maze[0][rnd].setDoorPos(2);
                flag[tmp] = true;
            }
        }
        while (maze[0][rnd].getDoorType() == "none");
        rnd = 2 + (int)(Math.random() * (size-3));
        do
        {
            tmp = (int)(Math.random() * 4);
            if (!flag[tmp]) // эта дверь ранее не устаналивалась
            {
                maze[size-1][rnd].setDoorType(tmp);
                maze[size-1][rnd].setDoorPos(3);
                flag[tmp] = true;
            }
        }
        while (maze[size-1][rnd].getDoorType() == "none");
        rnd = 2 + (int)(Math.random() * (size-3));
        do
        {
            tmp = (int)(Math.random() * 4);
            if (!flag[tmp]) // эта дверь ранее не устаналивалась
            {
                maze[rnd][0].setDoorType(tmp);
                maze[rnd][0].setDoorPos(0);
                flag[tmp] = true;
            }
        }
        while (maze[rnd][0].getDoorType() == "none");
        rnd = 2 + (int)(Math.random() * (size-3));
        for (int i = 0; i < 4; i++)
        {
            if (!flag[i])
            {
                maze[rnd][size-1].setDoorType(i);
                maze[rnd][size-1].setDoorPos(1);
                flag[i] = true;
            }
        }

        return maze;
    }

    public Cell[][] keySpawner(Cell[][] maze)
    {
        int rnd = 0, tmp = 0, type;
        boolean[] flag = {false, false, false, false};
        for (int i = 0; i < 4; i++)
        {
            do
            {
                switch (i)
                {
                    case 0: // 1 ЮЕФЧЕТФШ
                        rnd = (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ И
                        tmp = (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ Х
                        break;
                    case 1: // 2 ЮЕФЧЕТФШ
                        rnd = (int)(Math.random() * (size/2));  // ЗЕОЕТБГЙС ЛППТДЙОБФЩ И
                        tmp = size/2 + (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ Х
                        break;
                    case 2: // 3 ЮЕФЧЕТФШ
                        rnd = size/2 + (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ И
                        tmp = (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ Х
                        break;
                    case 3: // 4 ЮЕФЧЕТФШ
                        rnd = size/2 + (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ И
                        tmp = size/2 + (int)(Math.random() * (size/2)); // ЗЕОЕТБГЙС ЛППТДЙОБФЩ Х
                }
                if (maze[rnd][tmp].getContent() == "empty")
                {
                    type = (int)(Math.random() * 4);
                    if (!flag[type]) // ЬФПФ ЛМАЮ ТБОЕЕ ОЕ ХУФБОБМЙЧБМУС
                    {
                        maze[rnd][tmp].setKeyType(type);
                        maze[rnd][tmp].setContent("key");
                        flag[type] = true; // ВПМШЫЕ ЬФПФ ЛМАЮ ЙУРПМШЪПЧБФШ ОЕМШЪС
                    }
                }
            }
            while (maze[rnd][tmp].getKeyType() == "none");
        }
        return maze;
    }

//    public Cell[][] treasureSpawner(Cell[][] maze)
//    {
//        int rnd, tmp;
//        do
//        {
//            rnd = (int)(Math.random() * (size));
//            tmp = (int)(Math.random() * (size));
//            if (maze[rnd][tmp].getContent() == "empty")
//            {
//                maze[rnd][tmp].setContent("treasure");
//            }
//        }
//        while (maze[rnd][tmp].getContent() != "treasure");
//        return maze;
//    }

    public Cell[][] treasureSpawner(Cell[][] maze)
    {
        int rnd, tmp;
        do
        {
            rnd = (int)(Math.random() * (size));
            tmp = (int)(Math.random() * (size));
            if (((rnd != 0) && (tmp != 0)) && ((rnd != size - 1) && (tmp != size - 1)))
                if (maze[rnd][tmp].getContent() == "empty")
                {
                    maze[rnd][tmp].setContent("treasure");
                }
        }
        while (maze[rnd][tmp].getContent() != "treasure");
        return maze;
    }

//    public Cell[][] stickSpawner(Cell[][] maze)
//    {
//        int rnd, tmp;
//        int stickX = size, stickY = size;
//        for (int i = 0; i < 2; i++)
//        {
//            do
//            {
//                rnd = (int)(Math.random() * (size));
//                tmp = (int)(Math.random() * (size));
//                if (maze[rnd][tmp].getContent() == "empty")
//                {
//                    maze[rnd][tmp].setContent("stick");
//                }
//            }
//            while ((maze[rnd][tmp].getContent() != "stick") || ((rnd == stickX) && (tmp == stickY)));
//            stickX = rnd;
//            stickY = tmp;
//        }
//        return maze;
//    }

    public Cell[][] stickSpawner(Cell[][] maze)
    {
        int rnd, tmp;
        int stickX = size, stickY = size;
        for (int i = 0; i < 2; i++)
        {
            do
            {
                rnd = (int)(Math.random() * (size));
                tmp = (int)(Math.random() * (size));
                if (((rnd != 0) && (tmp != 0)) && ((rnd != size - 1) && (tmp != size - 1)))
                    if (maze[rnd][tmp].getContent() == "empty")
                    {
                        maze[rnd][tmp].setContent("stick");
                    }
            }
            while ((maze[rnd][tmp].getContent() != "stick") || ((rnd == stickX) && (tmp == stickY)));
            stickX = rnd;
            stickY = tmp;
        }
        return maze;
    }

//    public Cell[][] trapSpawner(Cell[][] maze)
//    {
//        int rnd=0, tmp=0, num=0;
//        String item="";
//        switch (size)
//        {
//            case 10:
//                num = 1;
//                break;
//            case 15:
//                num = 2;
//                break;
//            case 20:
//                num = 4;
//        }
//        for (int i = 0; i < num; i++)
//        {
//            for (int j = 0; j < 3; j++)
//            {
//                switch (j)
//                {
//                    case 0:
//                        item = "dart";
//                        break;
//                    case 1:
//                        item = "poisonDart";
//                        break;
//                    case 2:
//                        item = "trap";
//                }
//                do
//                {
//                    switch (num)
//                    {
//                        case 1:
//                            rnd = (int)(Math.random() * (size));
//                            tmp = (int)(Math.random() * (size));
//                            break;
//                        case 2:
//                            if (i == 0)
//                                rnd = (int)(Math.random() * (size/2));
//                            else
//                                rnd = size/2 + (int)(Math.random() * (size/2));
//                            tmp = (int)(Math.random() * (size));
//                            break;
//                        case 4:
//                            switch (i)
//                            {
//                                case 0: // 1 четверть
//                                    rnd = (int)(Math.random() * (size/2)); // генерация координаты х
//                                    tmp = (int)(Math.random() * (size/2)); // генерация координаты у
//                                    break;
//                                case 1: // 2 четверть
//                                    rnd = (int)(Math.random() * (size/2));  // генерация координаты х
//                                    tmp = size/2 + (int)(Math.random() * (size/2)); // генерация координаты у
//                                    break;
//                                case 2: // 3 четверть
//                                    rnd = size/2 + (int)(Math.random() * (size/2)); // генерация координаты х
//                                    tmp = (int)(Math.random() * (size/2)); // генерация координаты у
//                                    break;
//                                case 3: // 4 четверть
//                                    rnd = size/2 + (int)(Math.random() * (size/2)); // генерация координаты х
//                                    tmp = size/2 + (int)(Math.random() * (size/2)); // генерация координаты у
//                            }
//                    }
//                    if (maze[rnd][tmp].getContent() == "empty")
//                    {
//                        maze[rnd][tmp].setContent(item);
//                    }
//                }
//                while (maze[rnd][tmp].getContent() != item);
//            }
//        }
//        return maze;
//    }

    public Cell[][] trapSpawner(Cell[][] maze)
    {
        int rnd = 0, tmp = 0, num = 0;
        String item = "";
        switch (size)
        {
            case 10:
                num = 1;
                break;
            case 15:
                num = 2;
                break;
            case 20:
                num = 4;
        }
        for (int i = 0; i < num; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                switch (j)
                {
                    case 0:
                        item = "dart";
                        break;
                    case 1:
                        item = "poisonDart";
                        break;
                    case 2:
                        item = "trap";
                }
                do
                {
                    switch (num)
                    {
                        case 1:
                            rnd = (int)(Math.random() * (size));
                            tmp = (int)(Math.random() * (size));
                            break;
                        case 2:
                            if (i == 0)
                                rnd = (int)(Math.random() * (size/2));
                            else
                                rnd = size/2 + (int)(Math.random() * (size/2));
                            tmp = (int)(Math.random() * (size));
                            break;
                        case 4:
                            switch (i)
                            {
                                case 0: // 1 четверть
                                    rnd = (int)(Math.random() * (size/2)); // генерация координаты х
                                    tmp = (int)(Math.random() * (size/2)); // генерация координаты у
                                    break;
                                case 1: // 2 четверть
                                    rnd = (int)(Math.random() * (size/2));  // генерация координаты х
                                    tmp = size/2 + (int)(Math.random() * (size/2)); // генерация координаты у
                                    break;
                                case 2: // 3 четверть
                                    rnd = size/2 + (int)(Math.random() * (size/2)); // генерация координаты х
                                    tmp = (int)(Math.random() * (size/2)); // генерация координаты у
                                    break;
                                case 3: // 4 четверть
                                    rnd = size/2 + (int)(Math.random() * (size/2)); // генерация координаты х
                                    tmp = size/2 + (int)(Math.random() * (size/2)); // генерация координаты у
                            }
                    }
                    if (((rnd != 0) && (tmp != 0)) && ((rnd != size - 1) && (tmp != size - 1)))
                        if (maze[rnd][tmp].getContent() == "empty")
                        {
                            maze[rnd][tmp].setContent(item);
                        }
                }
                while (maze[rnd][tmp].getContent() != item);
            }
        }
        return maze;
    }

    public Cell[][] getMaze()
    {
        return board;
    }
}
